Unit in the last place

In computer science and numerical analysis, unit in the last place or unit of least precision (ULP) is the spacing between floating-point numbers, i.e., the value the least significant bit (lsb) represents if it is 1. It is used as a measure of precision in numeric calculations.

The IEEE 754 specification—followed by all modern floating-point hardware—requires that the result of an elementary arithmetic operation (addition, subtraction, multiplication, division, and square root) be within 0.5 ULP of the mathematically exact result—that is, that it be the best possible result. Reputable numeric libraries compute the basic transcendental functions to between 0.5 and about 1 ULP, as it is computationally expensive to guarantee 0.5 ULP precision.[1]

Contents

Example

If ULP(x) is less than or equal to 1, then x + 1 > x. Otherwise, x + 1 = x. This is demonstrated in the following Haskell code typed at an interactive prompt:

> until (\x -> x == x+1) (+1) 0 :: Float
1.6777216e7
> it-1
1.6777215e7
> it+1
1.6777216e7

Here we start with 0 in 32-bit single-precision and repeatedly add 1 until the operation is idempotent. The result is equal to 224 (in hex, 4b800000) since the significand for a single-precision number in this example contains 24 bits.

Another example, in Python, also typed at an interactive prompt, is:

>>> x = 1.0
>>> while (x != x + 1.0):
...   x = x * 2.0
... 
>>> x
9007199254740992.0
>>> from math import log
>>> log (x) / log (2)
53.0

In this case, we start with x = 1 and repeatedly double it until x + 1 = x. The result is 253, because the double-precision floating-point used a 53-bit significand.

Language support

Since Java 1.5, the Java standard library has included Math.ulp(double) and Math.ulp(float) functions, although they use a different definition of ulp. Specifically, it uses the next highest real number for positive numbers, or the next lowest for negative. The C language library maths.h provides the function nextafter to calculate the next double. The Boost C++ Libraries offer boost::math::float_distance(a, b) to calculate the floating point distance between two doubles.

References

See also